package com.sneakxy.cloudbase.platform.config;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.reflect.MethodUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;
import org.springframework.session.SessionRepository;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import com.sneakxy.cloudbase.platform.utils.feign.TokenHolder;
import com.sneakxy.cloudbase.platform.utils.web.signature.SignatureContext;
import com.sneakxy.cloudbase.platform.utils.web.signature.SignatureValidator;

import feign.RequestInterceptor;
import feign.RequestTemplate;

@Configuration
@ConfigurationProperties(prefix="signature")
public class FeignRequestConfig implements RequestInterceptor {
	
	private static final Logger LOG = LogManager.getLogger(FeignRequestConfig.class);
	
	@Lazy
	@Autowired
	private SignatureValidator signatureValidator;
	
	private String secretkey;
	
	@Lazy
	@Autowired
	private SessionRepository<?> sessionRepository;
	
	@Override
	public void apply(RequestTemplate template) {
		try {
	  		ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder
	                .getRequestAttributes();
	  		HttpServletRequest request = attributes.getRequest();
	  		HttpSession session = request.getSession();
	        //存储SESSION ID
	   		String sessionId = session.getId();
			if(StringUtils.isNotBlank(sessionId)) {
				template.header(TokenHolder.TOKEN_NAME, sessionId);
			}
			if(getSignatureValidator() != null) {
				String signature = getSignatureValidator().signature();
				//存储签名
				template.header(SignatureContext.SIGNATURE, signature);
			}
			//保存SESSION缓存数据
			saveSession(session);
		} catch(Exception e) {
			LOG.error("同步会话失败", e);
		}
	}

	protected void saveSession(HttpSession session) {
		try {
			if(sessionRepository != null) {
				Object redisSession = MethodUtils.invokeMethod(session, true, "getSession");
				MethodUtils.invokeMethod(sessionRepository, true, "save", redisSession);
			}
		} catch (Exception e) {
			LOG.error("保存session缓存数据失败", e);
		}
	}
	
	public SignatureValidator getSignatureValidator() {
		return signatureValidator;
	}

	public String getSecretkey() {
		return secretkey;
	}

	public void setSecretkey(String secretkey) {
		this.secretkey = secretkey;
	}

}
